<?php

namespace app\service;


use app\model\EntityModel;
use app\model\TaskModel;
use app\tool\SingletonTrait;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;


class ReviewService
{
    use SingletonTrait;

    public function __construct()
    {
    }

    /**
     * 获取审核详情列表
     * @param $planEpisodeIdList
     * @param $startTime
     * @param $endTime
     * @param $projectId
     * @param $stepCategoryIdList
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getReviewDetailList($planEpisodeIdList, $startTime, $endTime, $projectId, $stepCategoryIdList): array
    {
        $closedId = StatusService::getInstance()->byCode('closed')['id'];
        $field = [
            "get_json_string(task.`json`, 'task_project_review_options_id') review_options_id",
            "r_episode.link_id episode_id"
        ];
        $previewQDb = TaskModel::field($field)
            ->join('task_relation_tag r_step_category', "r_step_category.link_module_code in ('step_category','show_step_category') and r_step_category.task_id = task.id")
            ->join('task_relation_tag r_episode', "r_episode.link_module_code in ('episode') and r_episode.task_id = task.id")
            ->whereFieldRaw("get_json_string(task.`json`,'task_status')", '<>', $closedId)
            ->where('task.step_type', TaskModel::STEP_TYPE_STANDARD_REVIEW)
            ->whereIn('r_episode.link_id', $planEpisodeIdList);

        if (!empty($projectId)) {
            $previewQDb->where('task.project_id', $projectId);
        }
        if (!empty($stepCategoryIdList)) {
            $previewQDb->whereIn('r_step_category.link_id', $stepCategoryIdList);
        }
        if (!empty($endTime)) {
            $previewQDb->whereFieldRaw('task.plan_end_time', '<=', $endTime);
        }
        if (!empty($startTime)) {
            $previewQDb->whereFieldRaw('task.plan_end_time', '>=', $startTime);
        }
        $reviewEpisodeList = $previewQDb->group('r_episode.link_id,review_options_id')->select();
        if (empty($reviewEpisodeList)) {
            return [];
        }
        $tagConfig = OptionsService::getInstance()->getProjectReviewOptions($projectId);
        if (empty($tagConfig)) {
            return [];
        }
        $tagConfigMap = [];
        foreach ($tagConfig as $datum) {
            $tagConfigMap[$datum['id']] = $datum;
        }
        $reviewEpisodeIdList = [];
        $reviewEpisodeListGroupedByName = [];
        foreach ($reviewEpisodeList as $list) {
            $reviewEpisodeIdList[] = $list['episode_id'];
            $reviewEpisodeListGroupedByName[$list['review_options_id']][] = $list['episode_id'] ?? 0;
        }
        $episodeEntityCountQuery = TaskModel::field('count(distinct task.entity_id) entity_number,task.episode_id episode_id')
            ->join('entity', 'entity.id = task.entity_id')
            ->join('module', 'module.id = entity.module_id')
            ->where('task.step_type', TaskModel::STEP_TYPE_STEP)
            ->whereIn('task.episode_id', $planEpisodeIdList)
            ->whereFieldRaw("get_json_string(task.`json`,'task_status')", '<>', $closedId);
        if (!empty($reviewEpisodeIdList)) {
            $episodeEntityCountQuery->whereIn('task.episode_id', $reviewEpisodeIdList);
        }
        if (!empty($param['step_category_id_list'])) {
            $episodeEntityCountQuery->whereIn('task.step_category_id', $param['step_category_id_list']);
        }
        $episodeEntityTotal = $episodeEntityCountQuery->group('task.episode_id')->select();
        if (empty($episodeEntityTotal->toArray())) {
            return [];
        }
        $episodeList = EntityModel::field("id,name,code")->whereIn('id', $reviewEpisodeIdList)->select();
        if (empty($episodeList->toArray())) {
            return [];
        }
        $episodeMap = array_column($episodeList->toArray(), null, 'id');
        $episodeEntityTotalMap = array_column($episodeEntityTotal->toArray(), null, 'episode_id');

        $reviewDetailList = [];
        foreach ($reviewEpisodeListGroupedByName as $reviewOptionsId => $episodeIdList) {
            if (empty($reviewOptionsId)) {
                // tag 为空
                continue;
            }
            if (empty($tagConfigMap[$reviewOptionsId])) {
                // tag 找不到配置
                continue;
            }
            $tagConfigValue = $tagConfigMap[$reviewOptionsId];
            $tempMakingOverviewReviewDetailEpisodeList = [];
            foreach ($episodeIdList as $episodeId) {
                if (!empty($episodeMap[$episodeId])) {
                    continue;
                }
                $tempMakingOverviewReviewDetailEpisodeList[] = [
                    'episode_id' => $episodeId,
                    'episode_name' => $episodeMap[$episodeId]['name'] ?? '',
                    'entity_number' => intval($episodeEntityTotalMap[$episodeId]),
                ];
            }
            $reviewDetailList[] = [
                'name' => $tagConfigValue['name'],
                'change_percent' => intval($tagConfigMap[$reviewOptionsId]['json'][0]['repair_percent']),
                'episode_list' => $tempMakingOverviewReviewDetailEpisodeList
            ];
        }
        return $reviewDetailList;
    }

}